package com.ld.zookeeper.api;

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Id;
import org.apache.zookeeper.data.Stat;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;

/**
 * @author:ld
 * @create:2020-04-21 14:03
 * @description: zookeeper 原生API 操作访问控制列表（ACL）
 */
public class ZookeeperACL {

    //连接对象
    private ZooKeeper zooKeeper;

    //连接地址
    private final String IP = "127.0.0.1:2181";

    private CountDownLatch countDownLatch = new CountDownLatch(1);

    /**
     * 开启连接
     */
    @Before
    public void befor() throws IOException, InterruptedException {
        //创建连接，因为是异步连接的，需要等待连接成功才能使用
        // arg1：连接地址
        // arg2：超时时间
        // arg3：自定义监视器
        zooKeeper = new ZooKeeper(IP, 5000, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                //连接成功
                if(Event.KeeperState.SyncConnected.equals(watchedEvent.getState())){
                    countDownLatch.countDown();
                    System.out.println("连接成功......");
                }else if(Event.KeeperState.Disconnected.equals(watchedEvent.getState())){
                    System.out.println("连接失败......");
                }else if(Event.KeeperState.AuthFailed.equals(watchedEvent.getState())){
                    System.out.println("用户认证失败......");
                }
            }
        });
        //等待连接成功
        countDownLatch.await();
    }

    /**
     * 关闭连接
     * @throws InterruptedException
     */
    @After
    public void after() throws InterruptedException {
        zooKeeper.close();
    }

    /**
     * 同步获取节点acl
     */
    @Test
    public void getACL1() throws KeeperException, InterruptedException {
        Stat stat = new Stat();
        //arg1:节点路径
        //arg2:节点状态
        List<ACL> acl = zooKeeper.getACL("/acl", stat);
        System.out.println("访问控制列表：" + acl);
        System.out.println("节点版本号：" + stat.getVersion());
    }

    /**
     * 异步获取节点访问控制列表（ACL）
     */
    @Test
    public void getACL2() throws InterruptedException {
        Stat stat = new Stat();
        zooKeeper.getACL("/acl", stat, new AsyncCallback.ACLCallback() {
            @Override
            public void processResult(int i, String s, Object o, List<ACL> list, Stat stat) {
                //结果
                System.out.println("结果：" + i);
                //节点路径
                System.out.println("节点路径：" + s);
                //上下文对象
                System.out.println("上下文对象：" + o);
                //acl
                System.out.println("访问控制列表：" + list);
                //节点状态
                System.out.println("节点状态：" + stat.getVersion());
            }
        },"I am context");
        Thread.sleep(5000);
        System.out.println("结束");
    }

    /**
     * 同步设置acl
     */
    @Test
    public void setACL1() throws KeeperException, InterruptedException {
        List<ACL> list = new ArrayList<>();
        ACL acl = new ACL(31,new Id("ip","127.0.0.1"));
        list.add(acl);
        //arg1:节点路径
        //arg2:acl列表
        //arg3:acl版本号
        Stat stat = zooKeeper.setACL("/acl", list, -1);
        System.out.println("节点acl版本号：" + stat.getAversion());
    }

    /**
     * 异步设置acl
     */
    @Test
    public void setACL2() throws InterruptedException {
        List<ACL> list = new ArrayList<>();
        ACL acl = new ACL(31,new Id("world","anyone"));
        list.add(acl);
        zooKeeper.setACL("/acl", list, -1, new AsyncCallback.StatCallback() {
            @Override
            public void processResult(int i, String s, Object o, Stat stat) {
                //结果
                System.out.println("结果：" + i);
                //节点路径
                System.out.println("节点路径：" + s);
                //上下文对象
                System.out.println("上下文对象：" + o);
                //节点状态
                System.out.println("节点状态：" + stat.getVersion());
            }
        },"I am context");
        Thread.sleep(5000);
        System.out.println("结束");
    }
}
